package cn.mrcode.wxsdk.web.common.ticket.lifeCycle.distributed.strategy.master_old;

import cn.mrcode.wxsdk.core.dialogue.common.LogUtil;
import cn.mrcode.wxsdk.core.dialogue.common.PublicAccount;
import cn.mrcode.wxsdk.core.dialogue.common.distributed.ZkDistributedSingleNodeExecutor;
import cn.mrcode.wxsdk.core.dialogue.common.exception.ReqException;
import cn.mrcode.wxsdk.core.dialogue.common.exception.WxException;
import cn.mrcode.wxsdk.core.dialogue.common.log.LogTemplateUtil;
import cn.mrcode.wxsdk.web.common.ticket.TicketApi;
import cn.mrcode.wxsdk.web.protocol.base.JsApiTicketInfo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;

/**
 * @author zhuqiang
 * @version V1.0
 * @Description: 分布式 zookpeer维护ticket 实现类
 * @date 2015/9/28 12:01
 */
@Deprecated
public class ZkTicket extends ZkDistributedSingleNodeExecutor {
    private static Logger log = LoggerFactory.getLogger(ZkTicket.class);
    private ConcurrentHashMap<String, JsApiTicketInfo> ticketMap;
    private HashMap<String,PublicAccount> accountMap; //公众号map

    private ConcurrentHashMap<String, JsApiTicketInfo> taskMap;
    private DelayQueue<JsApiTicketInfo> queue = new DelayQueue<JsApiTicketInfo>();

    /**
     * 构建 执行器
     *
     * @param sessionTimeout 链接超时毫秒
     * @param zkServiceList  zk服务器地址，逗号隔开
     * @param rootPath       根目录 路径（不存在将被自动创建，最好存在） 例如： /wxBaseToken
     * @param ticketMap  使用引用类型，方便更新本地的ticket
     * @param accountMap 需要维护的 公众号
     */
    public ZkTicket(int sessionTimeout, String zkServiceList, String rootPath, ConcurrentHashMap<String, JsApiTicketInfo> ticketMap, HashMap<String,PublicAccount> accountMap) {
        super(sessionTimeout, zkServiceList, rootPath,ticketMap);
        this.accountMap = accountMap;
    }


    @Override
    protected void executor(ZkDistributedSingleNodeExecutor zkDistributedSingleNodeExecutor, String data) {
        //数据不为空，那么就不是第一次，把已经有的数据 添加进任务列表
        if(StringUtils.isNotBlank(data)){
            if(!data.contains("true")){
                List<JsApiTicketInfo> list = JSON.parseArray(data, JsApiTicketInfo.class);
                for (JsApiTicketInfo ati : list) {
                    String appID = ati.getAppID();
                    if(accountMap.containsKey(appID)){
                        taskMap.put(appID,ati);
                    }
                }
            }
        }
        initTicket(); // 检查是否有新增 公众号，需要去把列表中的开发者账户，token拿到
        new Thread(new TicketDistributedTask(zkDistributedSingleNodeExecutor,taskMap)).start();
        log.info(LogTemplateUtil.svMsg("接管执行更新任务","%s,id=%s,data=%s",getRootPath(),getThisPath(),data));
    }


    @Override
    protected void firstRefresh(String data,Object obj) {
        log.info(LogTemplateUtil.svMsg("首次获得数据","%s,id=%s,data=%s",getRootPath(),getThisPath()+"",data));
        ticketMap = (ConcurrentHashMap<String, JsApiTicketInfo>)obj;
        taskMap = new ConcurrentHashMap<String,JsApiTicketInfo>();
        this.refresh(data);
    }

    @Override
    protected void refresh(String data) {
        final String apiName = "刷新数据";
        taskMap.clear();
        if(StringUtils.isNotBlank(data)){
            if(!data.contains("true")) {
                List<JsApiTicketInfo> list = JSON.parseArray(data, JsApiTicketInfo.class);
                for (JsApiTicketInfo ati : list) {
                    String appID = ati.getAppID();
                    ticketMap.put(appID, ati);
                }
                log.info(LogTemplateUtil.svMsg(apiName,"%s;id=%s;将新数据已刷入本地缓存=%s",getRootPath(),getThisPath()+"", JSONObject.toJSONString(list)));
            }
        }
    }

    /**
     * 初始化 task 任务数据
     */
    private void initTicket() {
        for (Map.Entry<String,PublicAccount> ent:accountMap.entrySet()){
            String appId = ent.getKey();
            PublicAccount pa = ent.getValue();
            if(!taskMap.containsKey(appId)){ //如果不包含则需要 获取
                JsApiTicketInfo jsApiTicketInfo = null;
                try {
                    jsApiTicketInfo = TicketApi.getJsApiTicketInfo(appId, pa.getAppSecret());
                } catch (ReqException e) {
                    log.error(LogUtil.fromateLog(e));
                } catch (WxException e) {
                    log.error(LogUtil.fromateLog(e));
                }
                taskMap.put(appId,jsApiTicketInfo);
            }

        }
        // 把获取的数据 上传一份先
        Collection<JsApiTicketInfo> values = taskMap.values();
        List<JsApiTicketInfo> data = new ArrayList<JsApiTicketInfo>(values);
        this.writeData(JSON.toJSONString(data));
    }
}
